Function Get-FTPChildItem
{
	[OutputType('PSFTP.Item')]
	[CmdletBinding(
		SupportsShouldProcess=$True,
		ConfirmImpact="Low"
	)]
	Param(
		[parameter(ValueFromPipelineByPropertyName=$true,
			ValueFromPipeline=$true)]
		[String]$Path = "",
		$Session = "DefaultFTPSession",
		[parameter(ValueFromPipelineByPropertyName=$true)]
		[Switch]$Recurse,	
		[Int]$Depth = 0,		
		[String]$Filter = "*"
	)
	
	Begin
	{
		if($Session -isnot [String])
		{
			$CurrentSession = $Session
		}
		else
		{
			$CurrentSession = Get-Variable -Scope Global -Name $Session -ErrorAction SilentlyContinue -ValueOnly
		}
		
		if($CurrentSession -eq $null)
		{
			Write-Warning "Add-FTPItem: Cannot find session $Session. First use Set-FTPConnection to config FTP connection."
			Break
			Return
		}	
	}
	
	Process
	{
		Write-Debug "Native path: $Path"
		
		if($Path -match "ftp://")
		{
			$RequestUri = $Path
			Write-Verbose "Use original path: $RequestUri"
			
		}
		else
		{
			$RequestUri = $CurrentSession.RequestUri.OriginalString+"/"+$Path
			Write-Verbose "Add ftp:// at start: $RequestUri"
		}
		$RequestUri = [regex]::Replace($RequestUri, '/$', '')
		$RequestUri = [regex]::Replace($RequestUri, '/+', '/')
		$RequestUri = [regex]::Replace($RequestUri, '^ftp:/', 'ftp://')
		Write-Verbose "Remove additonal slash: $RequestUri"

		if($Depth -gt 0)
		{
			$CurrentDepth = [regex]::matches($RequestUri,"/").count
			if((Get-Variable -Scope Script -Name MaxDepth -ErrorAction SilentlyContinue) -eq $null)
			{
				New-Variable -Scope Script -Name MaxDepth -Value ([Int]$CurrentDepth +$Depth)
			}
		
			Write-Verbose "Auto enable recurse mode. Current depth / Max Depth: $CurrentDepth / $($Script:MaxDepth)"
			$Recurse = $true
		}

		
		if ($pscmdlet.ShouldProcess($RequestUri,"Get child items from ftp location")) 
		{	
			if((Get-FTPItemSize $RequestUri -Session $Session -Silent) -eq -1)
			{
				Write-Verbose "Path is directory"
				$ParentPath = $RequestUri
			}
			else
			{
				Write-Verbose "Path is file. Delete last file name to get parent path."
				$LastIndex = $RequestUri.LastIndexOf("/")
				$ParentPath = $RequestUri.SubString(0,$LastIndex)
			}
						
			[System.Net.FtpWebRequest]$Request = [System.Net.WebRequest]::Create($RequestUri)
			$Request.Credentials = $CurrentSession.Credentials
			$Request.EnableSsl = $CurrentSession.EnableSsl
			$Request.KeepAlive = $CurrentSession.KeepAlive
			$Request.UseBinary = $CurrentSession.UseBinary
			$Request.UsePassive = $CurrentSession.UsePassive
			
			$Request.Method = [System.Net.WebRequestMethods+FTP]::ListDirectoryDetails
			Write-Verbose "Use WebRequestMethods: $($Request.Method)"
			Try
			{
				$mode = "Unknown"
				[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$CurrentSession.ignoreCert}
				$Response = $Request.GetResponse()
				
				[System.IO.StreamReader]$Stream = New-Object System.IO.StreamReader($Response.GetResponseStream(),[System.Text.Encoding]::Default)

				$DirList = @()
				$ItemsCollection = @()
				Try
				{
					[string]$Line = $Stream.ReadLine()
					Write-Debug "Read Line: $Line"
				}
				Catch
				{
					$Line = $null
					Write-Debug "Line is null"
				}
				
				While ($Line)
				{
					if($mode -eq "Compatible" -or $mode -eq "Unknown")
					{
						$null, [string]$IsDirectory, [string]$Flag, [string]$Link, [string]$UserName, [string]$GroupName, [string]$Size, [string]$Date, [string]$Name = `
						[regex]::split($Line,'^([d-])([rwxt-]{9})\s+(\d{1,})\s+([.@A-Za-z0-9-]+)\s+([A-Za-z0-9-]+)\s+(\d{1,})\s+(\w+\s+\d{1,2}\s+\d{1,2}:?\d{2})\s+(.+?)\s?$',"SingleLine,IgnoreCase,IgnorePatternWhitespace")

						if($IsDirectory -eq "" -and $mode -eq "Unknown")
						{
							$mode = "IIS6"
						}
						elseif($mode -ne "Compatible")
						{
							$mode = "Compatible" #IIS7/Linux
						}
						
						if($mode -eq "Compatible")
						{
							$DatePart = $Date -split "\s+"
							$NewDateString = "$($DatePart[0]) $('{0:D2}' -f [int]$DatePart[1]) $($DatePart[2])"
							
							Try
							{
								if($DatePart[2] -match ":")
								{
									$Month = ([DateTime]::ParseExact($DatePart[0],"MMM",[System.Globalization.CultureInfo]::InvariantCulture)).Month
									if((Get-Date).Month -ge $Month)
									{
										$NewDate = [DateTime]::ParseExact($NewDateString,"MMM dd HH:mm",[System.Globalization.CultureInfo]::InvariantCulture)
									}
									else
									{
										$NewDate = ([DateTime]::ParseExact($NewDateString,"MMM dd HH:mm",[System.Globalization.CultureInfo]::InvariantCulture)).AddYears(-1)
									}
								}
								else
								{
									$NewDate = [DateTime]::ParseExact($NewDateString,"MMM dd yyyy",[System.Globalization.CultureInfo]::InvariantCulture)
								}
							}
							Catch
							{
								Write-Verbose "Can't parse date: $Date"
							}							
						}
					}
					
					if($mode -eq "IIS6")
					{
						$null, [string]$NewDate, [string]$IsDirectory, [string]$Size, [string]$Name = `
						[regex]::split($Line,'^(\d{2}-\d{2}-\d{2}\s+\d{2}:\d{2}[AP]M)\s+<*([DIR]*)>*\s+(\d*)\s+(.+).*$',"SingleLine,IgnoreCase")
						
						if($IsDirectory -eq "")
						{
							$IsDirectory = "-"
						}
					}
					
					Switch($Size)
					{
						{[int64]$_ -lt 1024} { $HFSize = $_+"B"; break }
						{[System.Math]::Round([int64]$_/1KB,0) -lt 1024} { $HFSize = [String]([System.Math]::Round($_/1KB,0))+"KB"; break }
						{[System.Math]::Round([int64]$_/1MB,0) -lt 1024} { $HFSize = [String]([System.Math]::Round($_/1MB,0))+"MB"; break }
						{[System.Math]::Round([int64]$_/1GB,0) -lt 1024} { $HFSize = [String]([System.Math]::Round($_/1GB,0))+"GB"; break }
						{[System.Math]::Round([int64]$_/1TB,0) -lt 1024} { $HFSize = [String]([System.Math]::Round($_/1TB,0))+"TB"; break }
						{[System.Math]::Round([int64]$_/1PB,0) -lt 1024} { $HFSize = [String]([System.Math]::Round($_/1PB,0))+"PB"; break }
					} 
					
					if($IsDirectory -eq "d" -or $IsDirectory -eq "DIR")
					{
						$HFSize = ""
					}
					
					if($ParentPath -match "\*|\?")
					{
						$LastIndex = $ParentPath.LastIndexOf("/")
						$ParentPath = $ParentPath.SubString(0,$LastIndex)
						$ParentPath.Trim() + "/" + $Name.Trim()
					}
					
					$LineObj = New-Object PSObject -Property @{
						Dir = $IsDirectory
						Right = $Flag
						Ln = $Link
						User = $UserName
						Group = $GroupName
						Size = $HFSize
						SizeInByte = $Size
						OrgModifiedDate = $Date
						ModifiedDate = $NewDate
						Name = $Name.Trim()
						FullName = $ParentPath.Trim() + "/" + $Name.Trim()
						Parent = $ParentPath.Trim()
                        adst=""
					}
					
					$LineObj.PSTypeNames.Clear()
					$LineObj.PSTypeNames.Add('PSFTP.Item')
			
					if($Recurse -and ($LineObj.Dir -eq "d" -or $LineObj.Dir -eq "DIR"))
					{
						$DirList += $LineObj
					}
					
					
					if($LineObj.Dir)
					{
						if($LineObj.Name -like $Filter)
						{
							Write-Debug "Filter accepted: $Filter"
							$ItemsCollection += $LineObj
						}
					}
					$Line = $Stream.ReadLine()
					Write-Debug "Read Line: $Line"
				}
				
				$Response.Close()
				
			
				
				if($ItemsCollection.count -eq 0)
				{
					Return 
				}
				else
				{
					Return $ItemsCollection | Sort-Object -Property @{Expression="Parent";Descending=$false}, @{Expression="Dir";Descending=$true}, @{Expression="Name";Descending=$false} 
				}
			}
			Catch
			{
				Write-Error $_.Exception.Message -ErrorAction Stop 
			}
		}
		
		if($CurrentDepth -ge $Script:MaxDepth)
		{
			Remove-Variable -Scope Script -Name CurrentDepth 
		}		
	}
	
	End{}
}